<?php
/**
 * Created by PhpStorm.
 * User: liyu
 * Date: 2018/4/17
 * Time: 上午11:10
 */

namespace app\api\controller\v1;


use app\api\controller\Base;
use app\api\model\LoginLog;
use app\api\model\ModelCode;
use app\api\validate\CommonValidate;
use think\Cache;
use think\Config;
use think\Cookie;
use think\Request;
use think\Session;

class UserAuth extends Base
{
    protected $loginType;  //存储登陆信息类型  session  cache  redis
    protected $guid;
    protected $member_info;
    protected $userInfo;
    protected $orgId;
    protected $orgRange;
    protected $notLoginAction = [
        'User' => [
            'login'
        ]
    ];

    /**
     * 构造函数 开启checkLoginGlobal
     */
    public function _initialize()
    {
        parent::_initialize(); // TODO: Change the autogenerated stub
        //获取config中定义的登录类型 "login_type"
        $this->loginType = Config::get("login_type") ? Config::get("login_type") : "session";
        list($version,$controller) = explode('.',Request::instance()->controller());
        $action = Request::instance()->action();
        $loginCheckArray = $this->notLoginAction;
        if (!(array_key_exists($controller,$loginCheckArray) && in_array($action,$loginCheckArray[$controller]))) {
            $this->checkLoginGlobal();
        }
    }

    /**
     * 检测是否登录
     * @return bool
     */
    public function checkLoginGlobal()
    {
        $check_success = false;
        switch ($this->loginType) {
            case 1;
            case "session";
                $this->guid = Session::get('guid', 'Global');
                $this->member_info = Session::get('member_info', 'Global');
                if ($this->guid && $this->member_info) {
                    $check_success = true;
                }
                break;
            case 2;
            case "cache";
                $session_id_check = Cookie::get("session_id");
                $this->guid = Cache::get("guid_{$session_id_check}");
                $this->member_info = Cache::get("member_info_{$session_id_check}");
                if ($this->guid && $this->member_info) {
                    $check_success = true;
                }
                //刷新 缓存有效期
                Cache::set("guid_{$session_id_check}", $this->guid);
                Cache::set("member_info_{$session_id_check}", $this->member_info);
                break;
            case 3:
            case "redis":
                (new CommonValidate())->goCheck('loginStatus');
                $token = Request::instance()->param('token');
                $session = cache("token:$token");
                if (empty($session)) {
                    set_error_exception('login_invalid');
                }
                $this->guid = $session['guid'];
                $this->member_info = $session;
                $userInfo = db()->table('t_user')->where(['guid'=>$session['guid']])->find();
                $org = db()->table('t_org')->field(['id','parent_id'])->select();
                $this->orgRange = $this->getOrgRange($org,$userInfo['org_id']);
                $this->userInfo = $userInfo;
                $this->orgId = (int)$userInfo['org_id'];
                if ($this->guid && $this->member_info) {
                    $check_success = true;
                }
                //刷新 缓存有效期
                Cache::set("token:$token",$session,3600*24*7);
                break;
        }
        return $check_success;

    }

    protected function getOrgRange($data,$pId)
    {
        static $ids = [];
        foreach($data as $k => $v)
        {
            if($v['parent_id'] == $pId)
            {        //父亲找到儿子
                $this->getOrgRange($data, $v['id']);
                $ids[] = $v['id'];
                unset($data[$k]);
            }
        }
        return $ids;
    }

    /**
     * 设置全局登录
     */
    public function setLoginGlobal($member_info = [], $login_code = 0)
    {
        $set_success = false ;
        if ($member_info) {
            switch ($this->loginType) {
                case 1:
                case "session":
                    Session::set('member_info', $member_info, 'Global');
                    Session::set('guid', $member_info['guid'], 'Global');
                    if ((Session::has("guid", "Global"))) {
                        $set_success = true;
                    }
                    break;
                case 2:
                case "cache":
                    $session_id = $this->create_gid("SN");
                    Cookie::set("session_id", $session_id);
                    Cache::set("member_info_$session_id", $member_info);
                    Cache::set("guid_$session_id", $member_info['guid']);
                    $session_id_check = Cookie::get("session_id");
                    if ((Cache::get("guid_{$session_id_check}"))) {
                        $set_success = true;
                    }
                    break;
                case 3:
                case "redis":
                    $token = $this->create_gid('TN');
                    Session::set('token',$token);
                    Cache::set("token:$token",['guid'=>$member_info['guid']],3600*24*7);
                    if ((Cache::get("token:$token"))) {
                        $set_success = true;
                    }
                    break;

            }
        }
        if (!$set_success) return false;
        //保存登录记录
        $this->saveLoginInfo($member_info['guid'],$login_code);

        return true;
    }

    /**
     * 全局退出
     * @return bool
     */
    protected function logoutGlobal(){
        switch ($this->loginType) {
            case 1:
            case "session":
                Session::delete('guid', 'Global');
                Session::delete('member_info', 'Global');
                break;
            case 2:
            case "cache":
                $session_id_check = Cookie::get("session_id");
                Cache::rm("guid_{$session_id_check}");
                Cache::rm("member_info_{$session_id_check}");
                Cookie::delete("session_id");
                break;
            case 3:
            case "redis":

                break;
        }
        $this->member_info = null;
        $this->guid = null;
        return true;
    }

    /**
     * 创建个性GUID
     * @param string $base_code
     * @return string
     */
    public function create_gid($base_code = '')
    {
        if (empty($base_code)) {
            $base_name = basename(str_replace('\\', '/', get_called_class()), '.php');
            $guid_list = ModelCode::$gid_list;
            $base_code = isset($guid_list[$base_name]) ? $guid_list[$base_name] : 'QT';
        }
        $guid = $base_code . strtoupper(uniqid()) . $this->builderRand(6);
        return $guid;
    }

    /**
     * 创建随机数
     * @param int $num  随机数位数
     * @return string
     */
    public function builderRand($num=8){
        return substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, $num);
    }

    protected function saveLoginInfo($guid,$code)
    {
        $data = [
            'guid' => $guid,
            'code' => $code
        ];
        (new LoginLog)->editData($data);
    }
}